import { createContext, useContext, useReducer, useMemo } from 'react';

/**
 * 游戏状态接口
 * 定义了游戏运行过程中需要维护的状态
 */
interface GameState {
  currentWord: string;    // 当前需要绘制的词语
  score: number;          // 当前得分
  gameProgress: number;   // 游戏进度（0-100）
}

/**
 * 游戏动作类型
 * 定义了可以改变游戏状态的所有动作
 */
type GameAction = 
  | { type: 'SET_WORD'; payload: string }           // 设置当前词语
  | { type: 'UPDATE_SCORE'; payload: number }       // 更新得分
  | { type: 'UPDATE_PROGRESS'; payload: number };   // 更新游戏进度

/**
 * 游戏上下文类型
 * 定义了通过 Context 提供给组件的状态和方法
 */
interface GameContextType {
  state: GameState;                                // 游戏状态
  dispatch: React.Dispatch<GameAction>;            // 状态更新方法
}

// 创建游戏上下文
const GameContext = createContext<GameContextType | undefined>(undefined);

/**
 * 游戏状态更新函数
 * 根据不同的动作类型更新游戏状态
 */
const gameReducer = (state: GameState, action: GameAction): GameState => {
  switch (action.type) {
    case 'SET_WORD':
      return { ...state, currentWord: action.payload };
    case 'UPDATE_SCORE':
      return { ...state, score: action.payload };
    case 'UPDATE_PROGRESS':
      return { ...state, gameProgress: action.payload };
    default:
      return state;
  }
};

/**
 * 游戏状态提供者组件
 * 使用 useReducer 管理游戏状态，并通过 Context 提供给子组件
 */
export function GameProvider({ children }: { children: React.ReactNode }) {
  // 初始化游戏状态
  const [state, dispatch] = useReducer(gameReducer, {
    currentWord: '',
    score: 0,
    gameProgress: 0
  });

  // 使用 useMemo 优化 context value，避免不必要的重渲染
  const contextValue = useMemo(
    () => ({ state, dispatch }),
    [state, dispatch]
  );

  return (
    <GameContext.Provider value={contextValue}>
      {children}
    </GameContext.Provider>
  );
}

/**
 * 游戏状态 Hook
 * 用于在组件中访问游戏状态和更新方法
 * 必须在 GameProvider 内部使用
 */
export function useGame() {
  const context = useContext(GameContext);
  if (context === undefined) {
    throw new Error('useGame must be used within a GameProvider');
  }
  return context;
}

/**
 * 游戏动作创建器
 * 提供创建各种游戏动作的工厂函数
 */
export const gameActions = {
  // 设置当前词语
  setWord: (word: string): GameAction => ({
    type: 'SET_WORD',
    payload: word
  }),
  // 更新得分
  updateScore: (score: number): GameAction => ({
    type: 'UPDATE_SCORE',
    payload: score
  }),
  // 更新游戏进度
  updateProgress: (progress: number): GameAction => ({
    type: 'UPDATE_PROGRESS',
    payload: progress
  })
};
